package com.example.qiniupload.service;

import com.example.qiniupload.config.QiniuProperties;
import com.example.qiniupload.dto.UploadResponse;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.UUID;

@Slf4j
@Service
@RequiredArgsConstructor
public class QiniuService {
    
    private final QiniuProperties qiniuProperties;
    
    /**
     * 上传文件到七牛云
     * 
     * @param file 要上传的文件
     * @return 上传响应
     */
    public UploadResponse uploadFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            return UploadResponse.error("文件不能为空");
        }
        
        try {
            // 获取上传凭证
            String upToken = getUploadToken();
            
            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String fileName = generateFileName(originalFilename);
            
            // 选择区域
            Configuration cfg = getConfiguration();
            UploadManager uploadManager = new UploadManager(cfg);
            
            // 上传文件
            Response response = uploadManager.put(file.getBytes(), fileName, upToken);
            
            // 解析上传成功的结果
            DefaultPutRet putRet = response.jsonToObject(DefaultPutRet.class);
            log.info("文件上传成功，key: {}, hash: {}", putRet.key, putRet.hash);
            
            // 构建文件URL
            String fileUrl = buildFileUrl(fileName);
            
            return UploadResponse.success(fileUrl, fileName, file.getSize());
            
        } catch (QiniuException e) {
            log.error("七牛云上传失败: {}", e.getMessage(), e);
            return UploadResponse.error("上传失败: " + e.getMessage());
        } catch (IOException e) {
            log.error("文件读取失败: {}", e.getMessage(), e);
            return UploadResponse.error("文件读取失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("上传过程发生错误: {}", e.getMessage(), e);
            return UploadResponse.error("上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取上传凭证
     * 
     * @return 上传凭证
     */
    private String getUploadToken() {
        Auth auth = Auth.create(qiniuProperties.getAccessKey(), qiniuProperties.getSecretKey());
        return auth.uploadToken(qiniuProperties.getBucket());
    }
    
    /**
     * 生成文件名
     * 
     * @param originalFilename 原始文件名
     * @return 生成的文件名
     */
    private String generateFileName(String originalFilename) {
        if (originalFilename == null || originalFilename.isEmpty()) {
            return UUID.randomUUID().toString();
        }
        
        // 获取文件扩展名
        String extension = "";
        int lastDotIndex = originalFilename.lastIndexOf('.');
        if (lastDotIndex > 0) {
            extension = originalFilename.substring(lastDotIndex);
        }
        
        // 生成新的文件名
        return UUID.randomUUID().toString() + extension;
    }
    
    /**
     * 构建文件URL
     * 
     * @param fileName 文件名
     * @return 完整的文件URL
     */
    private String buildFileUrl(String fileName) {
        String domain = qiniuProperties.getDomain();
        if (!domain.endsWith("/")) {
            domain = domain + "/";
        }
        return domain + fileName;
    }
    
    /**
     * 获取七牛云配置
     * 
     * @return 配置对象
     */
    private Configuration getConfiguration() {
        String region = qiniuProperties.getRegion();
        if (region == null || region.isEmpty()) {
            region = "z0"; // 默认华东区域
        }
        
        switch (region) {
            case "z0":
                return new Configuration(Region.region0()); // 华东
            case "z1":
                return new Configuration(Region.region1()); // 华北
            case "z2":
                return new Configuration(Region.region2()); // 华南
            case "na0":
                return new Configuration(Region.regionNa0()); // 北美
            case "as0":
                return new Configuration(Region.regionAs0()); // 东南亚
            default:
                return new Configuration(Region.region0()); // 默认华东
        }
    }
}
